﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using LeadThing.AbpZeroTemplate.WorkFlow_Runs.Authorization;
using LeadThing.AbpZeroTemplate.WorkFlow_Runs.Dtos;
using LeadThing.AbpZeroTemplate.Dto;
using LeadThing.AbpZeroTemplate.WorkFlow_Run_Processs.Dtos;
using LeadThing.AbpZeroTemplate.WorkFlow_Run_Processs;
using LeadThing.AbpZeroTemplate.WorkFlow_Processs;

namespace LeadThing.AbpZeroTemplate.WorkFlow_Runs
{
    /// <summary>
    /// 流程实例服务实现
    /// </summary>
    //[AbpAuthorize(WorkFlow_RunAppPermissions.WorkFlow_Run)]


    public class WorkFlow_RunAppService : AbpZeroTemplateAppServiceBase, IWorkFlow_RunAppService
    {
        private readonly IRepository<WorkFlow_Run, long> _workFlow_RunRepository;
        private readonly IWorkFlow_RunListExcelExporter _workFlow_RunListExcelExporter;
        private readonly IRepository<WorkFlow_Run_Process, long> _workFlow_Run_ProcessRepository;//实例节点流转明细
        private readonly IRepository<WorkFlow_Process, long> _workFlow_ProcessRepository;


        private readonly WorkFlow_RunManage _workFlow_RunManage;
        /// <summary>
        /// 构造方法
        /// </summary>
        public WorkFlow_RunAppService(IRepository<WorkFlow_Run, long> workFlow_RunRepository,
        WorkFlow_RunManage workFlow_RunManage
      , IWorkFlow_RunListExcelExporter workFlow_RunListExcelExporter
      , IRepository<WorkFlow_Run_Process, long> workFlow_Run_ProcessRepository
      , IRepository<WorkFlow_Process, long> workFlow_ProcessRepository
  )
        {
            _workFlow_RunRepository = workFlow_RunRepository;
            _workFlow_RunManage = workFlow_RunManage;
            _workFlow_RunListExcelExporter = workFlow_RunListExcelExporter;
            _workFlow_Run_ProcessRepository = workFlow_Run_ProcessRepository;
            _workFlow_ProcessRepository = workFlow_ProcessRepository;
        }


        #region 实体的自定义扩展方法
        private IQueryable<WorkFlow_Run> _workFlow_RunRepositoryAsNoTrack => _workFlow_RunRepository.GetAll().AsNoTracking();

        /// <summary>
        /// 根据DetailID获取所有的流程节点明细
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ListResultDto<WorkFlow_Run_ProcessListDto>> GetAllWorkFlow_Run_ProcessListByDetailID(GetWorkFlow_RunInput input)
        {
            var wf_Process = (from process in _workFlow_ProcessRepository.GetAll()
                              where process.Id == input.ProcessID
                              select new { process.FlowID }).FirstOrDefault();

            var workflowList = from wf_run in _workFlow_RunRepository.GetAll()
                               join wf_run_process in _workFlow_Run_ProcessRepository.GetAll()
                               on wf_run.Id equals wf_run_process.RunID
                               where wf_run.DetailID == input.DetailID && wf_run.FlowID == wf_Process.FlowID
                               select new { wf_run_process };
            var items = await workflowList.ToListAsync();

            return new ListResultDto<WorkFlow_Run_ProcessListDto>(
                items.Select(item =>
                {
                    var dto = item.wf_run_process.MapTo<WorkFlow_Run_ProcessListDto>();
                    return dto;
                }).ToList());
        }

        #endregion


        #region 流程实例管理

        /// <summary>
        /// 根据查询条件获取流程实例分页列表
        /// </summary>
        public async Task<PagedResultDto<WorkFlow_RunListDto>> GetPagedWorkFlow_RunsAsync(GetWorkFlow_RunInput input)
        {

            var query = _workFlow_RunRepositoryAsNoTrack;
            //TODO:根据传入的参数添加过滤条件

            var workFlow_RunCount = await query.CountAsync();

            var workFlow_Runs = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var workFlow_RunListDtos = workFlow_Runs.MapTo<List<WorkFlow_RunListDto>>();
            return new PagedResultDto<WorkFlow_RunListDto>(
            workFlow_RunCount,
            workFlow_RunListDtos
            );
        }

        /// <summary>
        /// 通过Id获取流程实例信息进行编辑或修改 
        /// </summary>
        public async Task<GetWorkFlow_RunForEditOutput> GetWorkFlow_RunForEditAsync(NullableIdDto<long> input)
        {
            var output = new GetWorkFlow_RunForEditOutput();

            WorkFlow_RunEditDto workFlow_RunEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _workFlow_RunRepository.GetAsync(input.Id.Value);
                workFlow_RunEditDto = entity.MapTo<WorkFlow_RunEditDto>();
            }
            else
            {
                workFlow_RunEditDto = new WorkFlow_RunEditDto();
            }

            output.WorkFlow_Run = workFlow_RunEditDto;
            return output;
        }


        /// <summary>
        /// 通过指定id获取流程实例ListDto信息
        /// </summary>
        public async Task<WorkFlow_RunListDto> GetWorkFlow_RunByIdAsync(EntityDto<long> input)
        {
            var entity = await _workFlow_RunRepository.GetAsync(input.Id);

            return entity.MapTo<WorkFlow_RunListDto>();
        }







        /// <summary>
        /// 新增或更改流程实例
        /// </summary>
        public async Task CreateOrUpdateWorkFlow_RunAsync(CreateOrUpdateWorkFlow_RunInput input)
        {
            if (input.WorkFlow_RunEditDto.Id.HasValue)
            {
                await UpdateWorkFlow_RunAsync(input.WorkFlow_RunEditDto);
            }
            else
            {
                await CreateWorkFlow_RunAsync(input.WorkFlow_RunEditDto);
            }
        }

        /// <summary>
        /// 新增流程实例
        /// </summary>
        //[AbpAuthorize(WorkFlow_RunAppPermissions.WorkFlow_Run_CreateWorkFlow_Run)]
        public virtual async Task<WorkFlow_RunEditDto> CreateWorkFlow_RunAsync(WorkFlow_RunEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = input.MapTo<WorkFlow_Run>();

            entity = await _workFlow_RunRepository.InsertAsync(entity);
            return entity.MapTo<WorkFlow_RunEditDto>();
        }

        /// <summary>
        /// 编辑流程实例
        /// </summary>
        //[AbpAuthorize(WorkFlow_RunAppPermissions.WorkFlow_Run_EditWorkFlow_Run)]
        public virtual async Task UpdateWorkFlow_RunAsync(WorkFlow_RunEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _workFlow_RunRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _workFlow_RunRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除流程实例
        /// </summary>
        //[AbpAuthorize(WorkFlow_RunAppPermissions.WorkFlow_Run_DeleteWorkFlow_Run)]
        public async Task DeleteWorkFlow_RunAsync(EntityDto<long> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _workFlow_RunRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除流程实例
        /// </summary>
        //[AbpAuthorize(WorkFlow_RunAppPermissions.WorkFlow_Run_DeleteWorkFlow_Run)]
        public async Task BatchDeleteWorkFlow_RunAsync(List<long> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _workFlow_RunRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        #endregion

        #region 流程实例的Excel导出功能


        public async Task<FileDto> GetWorkFlow_RunToExcel()
        {
            var entities = await _workFlow_RunRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<WorkFlow_RunListDto>>();

            var fileDto = _workFlow_RunListExcelExporter.ExportWorkFlow_RunToFile(dtos);



            return fileDto;
        }


        #endregion

    }
}
